import _ from 'lodash'
import {computed, onMounted, onUnmounted, ref, watch} from "vue";
import { $utils, $bus } from "@jzl/utils";

// def defPath
export function useMask(props, emit) {

  let interval = null;
  const elements = ref([]);
  const masks = ref([]); // 做多10个？
  let isResizing = false;
  let isDragging = false;

  // let startX, startY, startWidth, startHeight;
  const container = computed(() => {
    return props.container || document.querySelector('.jzl-page-body');
  })

  const fixMaskPosition = (el) => {
    const rect = el?.getBoundingClientRect();
    const containerRect = container.value?.getBoundingClientRect();
    const scrollLeft = container.value?.scrollLeft || 0;
    const scrollTop = container.value?.scrollTop || 0;

    return {
      left: Math.floor(rect?.left - (containerRect?.left || 0)) + scrollLeft,
      top: Math.floor(rect?.top - (containerRect?.top || 0)) + scrollTop,
      width: Math.floor(rect?.width),
      height: Math.floor(rect?.height),
    }
    // mask.style.left = `${ rect?.left }px`;
    // mask.style.top = `${ rect?.top }px`;
    // mask.style.width = `${ rect?.width }px`;
    // mask.style.height = `${ rect?.height }px`;
  }

  // 仅修复遮罩层位置
  const fixMasks = _.throttle(() => {

    if(isResizing || isDragging) return;

    let els = elements.value;

    for(let i = 0; i < els.length; i++) {
      let el = els[i];
      let mask = masks.value[i];
      let newPos = fixMaskPosition(el);
      if(mask && (mask.left !== newPos.left || mask.top !== newPos.top || mask.width !== newPos.width || mask.height !== newPos.height)) {
        Object.assign(mask, newPos, { code: $utils.getNanoid() })
      }

      // Object.assign(mask, newPos, { code: $utils.getNanoid() })
    }
  }, 100)

  const refreshMask = _.throttle((reRender = false) => {
    let els = elements.value;
    let elsLen = els?.length || 0;
    if(elsLen < masks.value.length) {
      masks.value.forEach((mask, index) => {
        if(index >= elsLen) {
          mask.show = false;
        }
      })
    }

    if(elsLen <= 0) return;

    const computedStyle = window.getComputedStyle(els[0]);
    const position = computedStyle.getPropertyValue('position');

    for(let i = 0; i < els.length; i++) {
      let el = els[i];
      let mask = masks.value[i];
      if(!mask) {
        mask = {
          show: true,
          code: $utils.getNanoid(),
          position: position
        }
      }

      if(reRender) mask.code = $utils.getNanoid();
      Object.assign(mask, {
        show: true,
        active: true,
        isRoot: props.currentItem?.ele_style?._code === props.currentElCode
      }, fixMaskPosition(el))
      masks.value[i] = mask;

      // 调整手柄位置（右下角）
      // resizeHandle.style.left = `${rect.width - 5}px`;
      // resizeHandle.style.top = `${rect.height - 5}px`;
    }
  }, 500)

  const clearMask = () => {
    masks.value?.forEach(mask => {
      mask.show = false;
    })
  }

  const onResizeStart = (a1, a2, a3) => {
    // console.log('----- onResizeStart: ', a1, a2, a3)
    isResizing = true;
    // $bus.emit('design:clearHoverMask')
  }

  const onResizing = (l, t, w, h) => {
    // console.log('----- onResizing: ', l, t, w, h)
    // console.log(props.currentNode.def)
    props.currentNode.def._ss.width = w;
    props.currentNode.def._ss.height = h;
  }

  const onResizeStop = (l, t, w, h) => {
    // console.log('----- onResizeStop: ', l, t, w, h)
    isResizing = false;
    // 修改遮罩层
    refreshMask()
// console.log(`----- onResizeStop l: ${ l }, t: ${ t }, w: ${ w }, h: ${ h }`)
    props.currentNode.def._ss.width = w;
    props.currentNode.def._ss.height = h;
    $bus.emit('design:clearHoverMask')
  }

  const onDragStart = (x, y) => {
    isDragging = true;

    // return false; — for cancel
  }

  const onDragging = (x, y) => {
    props.currentNode.def._ss.left = x;
    props.currentNode.def._ss.top = y;
  }

  const onDragStop = (x, y) =>  {
    // console.log('----- onDragStop: ', x, y)
    props.currentNode.def._ss.left = x;
    props.currentNode.def._ss.top = y;

    // console.log(`----- onDragStop x: ${ x }, y: ${ y }`)

    $bus.emit('design:clearHoverMask')

    refreshMask();
    isDragging = false;
  }

  const initMask = () => {
    setTimeout(()=> {
      let focusCode = /*props.hoverItemElCode || */props.currentElCode;
      if(!focusCode) return;

      elements.value = (props.container || document).querySelectorAll(`[j-name=${focusCode}]`);
      refreshMask()
    }, 50);
  }

  watch(() => props.currentItem, () => {
    initMask();
  }, { deep: true })

  watch(
    () => [ props.currentElCode /*, props.hoverItemElCode*/ ],
    () => initMask()
  );

  /*watch(() => elements.value, (els) => {
    _refreshMask()
  }, { deep: true })*/

  onMounted(() => {
    if (typeof window !== 'undefined') {
      window.addEventListener('resize', refreshMask)
    }

    $bus.on('design:refreshMask', refreshMask)
    $bus.on('design:clearMask', clearMask)
    if(interval) clearInterval(interval)
    interval = setInterval(fixMasks, 500)
  });

  onUnmounted(() => {
    window.removeEventListener('resize', refreshMask)

    $bus.off('design:refreshMask', refreshMask)
    $bus.off('design:clearMask', clearMask)
    if(interval) {
      clearInterval(interval)
      interval = null;
    }

    clearMask()
  });

  return {
    masks,
    refreshMask,
    clearMask,
    onResizeStart,
    onResizing,
    onResizeStop,

    onDragStart,
    onDragging,
    onDragStop,
  }
}
